package drds.checksum;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;

import com.google.common.base.Joiner;

import drds.common.$;

public class Crc32s {
	/**
	 * 
	 * @param tableName
	 * @param columnNames
	 * @param whereCondition 一个是主键 一个是时间段 按照天进行计算
	 * @param map
	 * @return
	 * @throws SQLException
	 */
	public static boolean createCrc32(String tableName, String[] columnNames, String whereCondition,
			Map<String, String> map) throws SQLException {
		//
		/**
		 * <pre>
		 * update u  set crc32_string =(CONCAT_WS('_',(case when name is not null then CRC32(name) else  '~' end),(case when x is not null then CRC32(x) else  '~' end))),crc32=CRC32(crc32_string)  WHERE id >=1 and id<=2;
		 * </pre>
		 */
		String crc32OfColumnTemplate = "(case when ${columnName} is not null then CRC32(${columnName}) else  '~' end)";
		List<String> crc32OfColumnList = new LinkedList<String>();
		for (String columnName : columnNames) {
			String crc32OfColumn = crc32OfColumnTemplate.concat("").replace("${columnName}", columnName);
			crc32OfColumnList.add(crc32OfColumn);
		}
		String crc32OfColumns = Joiner.on(",").skipNulls().join(crc32OfColumnList);
		String sql = "update ${tableName} set crc32_string =(concat_ws('_',${crc32OfColumns})),crc32=crc32(crc32_string)"
				.replace("${tableName}", tableName)//
				.replace("${crc32OfColumns}", crc32OfColumns)//
				+ whereCondition;
		System.out.println(sql);

		Connection connection = drds.checksum.DbUtils.getConnection(map);
		QueryRunner queryRunner = new QueryRunner();
		queryRunner.update(connection, sql);
		DbUtils.closeQuietly(connection);
		return true;

	}

	/**
	 * <pre>
	   *    存在N种情况
	 * m有s无(inc version即可)
	 * m无s有(这种情况需要等待分钟,如果s还存在则需要删除)
	 * 
	 * 
	 * ms不一致(inc version即可)
	 * ms一致(不需要管)
	 * 
	 * 
	   *    处理规则在10000条数据存下差异的情况下,按照100条数据<标准>的形式分成100组
	 * </pre>
	 */
	// 450215437_~ 3541158808
	// 1842515611_~ 1499527503
	// 0_~ 1370759458
	// ~_~ 732987880*/
	public static TreeMap<String, String> crc32Compare(String[] columnNames, TreeMap<String, String> masterTreeMap,
			TreeMap<String, String> slaveTreeMap) {

		TreeMap<String, String> result = new TreeMap<String, String>();
		// 针对每个字段进行对比
		// 需要输出两个数据行在哪个字段不一样,然后以表的形式进行写入表里面
		//
		// 先需要找出两个集合互相不存在的值。这些值直接进行处理
		// 1
		TreeSet<String> masterTreeSet = new TreeSet<String>();
		masterTreeSet.addAll(masterTreeMap.keySet());
		// 2
		TreeSet<String> masterTreeSetCopy = new TreeSet<String>();
		masterTreeSetCopy.addAll(masterTreeMap.keySet());
		//
		TreeSet<String> slaveTreeSet = new TreeSet<String>();
		slaveTreeSet.addAll(slaveTreeMap.keySet());
		//
		masterTreeSet.removeAll(slaveTreeSet);
		slaveTreeSet.removeAll(masterTreeSetCopy);
		masterTreeSetCopy.clear();
		masterTreeSetCopy = null;
		//
		for (String key : masterTreeSet) {
			result.put(key, "master多");
		}
		for (String key : slaveTreeSet) {
			result.put(key, "slave多");
		}
		//
		//
		for (String key : masterTreeMap.keySet()) {
			if (masterTreeSet.contains(key) || slaveTreeSet.contains(key)) {
				continue;// 互相不存在
			}
			//
			String crc32String1 = masterTreeMap.get(key);
			String crc32String2 = slaveTreeMap.get(key);
			//
			String[] crc32String1Splits = crc32String1.split("_");
			String[] crc32String2Splits = crc32String2.split("_");
			//
			List<String> containDifferencesColumnNameList = new LinkedList<String>();
			for (int i = 0; i < columnNames.length; i++) {
				//
				if (!crc32String1Splits[i].equals(crc32String2Splits[i])) {
					String columnName = columnNames[i];
					containDifferencesColumnNameList.add(columnName);
				}
			}
			if ($.isHasData(containDifferencesColumnNameList)) {
				String containDifferencesColumnNamesString = Joiner.on(",").skipNulls()
						.join(containDifferencesColumnNameList);
				result.put(key, "存在差异的字段:" + containDifferencesColumnNamesString);
			}

		}

		return result;
	}

}
